package com.tubeonfire.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.google.gdata.client.youtube.YouTubeQuery;
import com.google.gdata.client.youtube.YouTubeService;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.data.youtube.VideoFeed;

import com.google.gdata.util.ServiceException;
import com.tubeonfire.entity.Tube;
import com.tubeonfire.entity.TubesFeed;
import com.tubeonfire.model.TubeModel;

public class TubeService {

	private static int itemPerPage = 12;
	public static YouTubeService service = new YouTubeService("tubeonfire"); // can
																				// change
																				// service
																				// name.

	public static TubesFeed searchByKey(String key, int page, int type) {
		TubesFeed result = new TubesFeed();
		List<Tube> listTube = new ArrayList<Tube>();
		System.out.println("Searching...");
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/videos"));
			query.setFullTextQuery(key);
			query.setMaxResults(itemPerPage);
			query.setStartIndex(itemPerPage * page);
			query.setSafeSearch(YouTubeQuery.SafeSearch.NONE);
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			result.setTotalResult(videoFeed.getTotalResults());
			result.setCurrentPage(page);
			List<Tube> listSave2DB = new ArrayList<Tube>();
			for (VideoEntry videoEntry : videoFeed.getEntries()) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				listTube.add(tub);
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle().getValue()
							+ " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
			TubeModel.closePM();
		} catch (MalformedURLException e) {
			System.out.println("Error when searching with key : + " + key);
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("Error when searching with key : + " + key);
			e.printStackTrace();
		} catch (ServiceException e) {
			System.out.println("Error when searching with key : + " + key);
			e.printStackTrace();
		}
		result.setListTube(listTube);
		return result;
	}

	public static Tube searchById(String id) {
		Tube tub = new Tube();
		try {
			tub = TubeModel.getByTubeId(id);
			if (tub != null) {
				if ((tub.getStatus() == 2) || !tub.isUpdate()) {
					System.out.println("Update from youtube : " + id);
					String videoEntryUrl = "http://gdata.youtube.com/feeds/api/videos/"
							+ id;
					VideoEntry videoEntry = service.getEntry(new URL(
							videoEntryUrl), VideoEntry.class);
					tub.transformVideoEntry(videoEntry);
					TubeModel.update(tub);
					TubeModel.closePM();

					System.out.println("Save to database success !");
				} else {
					System.out.println("Get detail from database : " + id);
				}
			}
			return tub;
		} catch (MalformedURLException e) {
			System.out.println("Error when searching with id : + " + id);
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("Error when searching with id : + " + id);
			e.printStackTrace();
		} catch (ServiceException e) {
			System.out.println("Error when searching with id : + " + id);
			e.printStackTrace();
		}
		return tub;
	}

	public static TubesFeed getMostView(String time, int itemPerPage, int page) {
		TubesFeed result = new TubesFeed();
		List<Tube> listTube = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		int startIndex = 1;
		if (page != 1) {
			startIndex = itemPerPage * page;
		}
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/standardfeeds/most_viewed?time="
							+ time + "&start-index=" + startIndex
							+ "&max-results=" + itemPerPage
							+ "&orderby=viewCount&v=2"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			result.setTotalResult(videoFeed.getTotalResults());
			result.setCurrentPage(page);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				listTube.add(tub);
				System.out.println(tub.getTubeId());
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
			result.setListTube(listTube);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public static List<Tube> getMostPopular(String time) {
		List<Tube> result = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/standardfeeds/most_popular?time="
							+ time + "&max-results=6&orderby=viewCount&v=2"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				result.add(tub);
				System.out.println(tub.getTubeId());
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public static List<Tube> getMostRecent() {
		List<Tube> result = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		try {
			YouTubeQuery query = new YouTubeQuery(
					new URL(
							"https://gdata.youtube.com/feeds/api/standardfeeds/most_recent?max-results=9"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				result.add(tub);
				System.out.println(tub.getTubeId());
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public static TubesFeed getMostShared(int itemPerPage, int page) {
		TubesFeed result = new TubesFeed();
		List<Tube> listTube = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		int startIndex = 1;
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/standardfeeds/most_shared?start-index="
							+ startIndex + "&max-results=" + itemPerPage
							+ "&orderby=viewCount"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			result.setTotalResult(videoFeed.getTotalResults());
			result.setCurrentPage(page);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				listTube.add(tub);
				System.out.println(tub.getTubeId());
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
			result.setListTube(listTube);
		} catch (MalformedURLException e) {
			System.out.println("Malformed exception.");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("IO exception.");
			e.printStackTrace();
		} catch (ServiceException e) {
			System.out.println("Service exception.");
			e.printStackTrace();
		}
		return result;
	}

	public static TubesFeed getMostDiscussed(String time, int itemPerPage, int page) {
		TubesFeed result = new TubesFeed();
		List<Tube> listTube = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		int startIndex = 1;
		if (page != 1) {
			startIndex = itemPerPage * page;
		}
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/standardfeeds/most_discussed?time="
							+ time + "&start-index=" + startIndex
							+ "&max-results=" + itemPerPage
							+ "&orderby=viewCount&v=2"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			result.setTotalResult(videoFeed.getTotalResults());
			result.setCurrentPage(page);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				listTube.add(tub);				
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
			result.setListTube(listTube);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public static TubesFeed getTopRate(String time, int itemPerPage, int page) {
		TubesFeed result = new TubesFeed();
		List<Tube> listTube = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		int startIndex = 1;
		if (page != 1) {
			startIndex = itemPerPage * page;
		}
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/standardfeeds/top_rated?time="
							+ time + "&start-index=" + startIndex
							+ "&max-results=" + itemPerPage
							+ "&orderby=viewCount&v=2"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			result.setTotalResult(videoFeed.getTotalResults());
			result.setCurrentPage(page);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				listTube.add(tub);
				System.out.println(tub.getTubeId());
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
			result.setListTube(listTube);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public static TubesFeed getTopFavorites(String time, int itemPerPage, int page) {
		TubesFeed result = new TubesFeed();
		List<Tube> listTube = new ArrayList<Tube>();
		List<Tube> listSave2DB = new ArrayList<Tube>();
		int startIndex = 1;
		if (page != 1) {
			startIndex = itemPerPage * page;
		}
		try {
			YouTubeQuery query = new YouTubeQuery(new URL(
					"https://gdata.youtube.com/feeds/api/standardfeeds/top_favorites?time="
							+ time + "&start-index=" + startIndex
							+ "&max-results=" + itemPerPage
							+ "&orderby=viewCount&v=2"));
			VideoFeed videoFeed = service.query(query, VideoFeed.class);
			result.setTotalResult(videoFeed.getTotalResults());
			result.setCurrentPage(page);
			List<VideoEntry> videos = videoFeed.getEntries();
			for (VideoEntry videoEntry : videos) {
				Tube tub = new Tube();
				tub.transformHalfVideoEntry(videoEntry);
				tub.setStatus(2);
				tub.setUpdated(Calendar.getInstance().getTime());
				listTube.add(tub);				
				if (TubeModel.getByTubeId(tub.getTubeId()) == null) {
					listSave2DB.add(tub);
					System.out.println(tub.getTitle() + " ready to save !");
				}
			}
			if (listSave2DB.size() > 0) {
				TubeModel.addAll(listSave2DB);
				System.out.println("Saved " + listSave2DB.size()
						+ " video success !");
			}
			result.setListTube(listTube);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
}
